package com.mingqijia.gassafety.webserver.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.mingqijia.gassafety.db.entity.*;
import com.mingqijia.gassafety.db.mapper.*;
import com.mingqijia.gassafety.shared.constant.BusinessNoticeParam;
import com.mingqijia.gassafety.shared.constant.Constants;
import com.mingqijia.gassafety.shared.dto.tcis.CancelBusiOrderDTO;
import com.mingqijia.gassafety.shared.dto.OrderCancelDTO;
import com.mingqijia.gassafety.webserver.service.*;
import com.mingqijia.gassafety.webserver.service.workorder.AsstWorkOrderService;
import com.mingqijia.gassafety.webserver.service.workorder.mbp.TcisService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 工单处理
 */
@Service
@Slf4j
public class WorkOrderHandleServiceImpl implements WorkOrderHandleService {

    @Resource
    FieldTemplateService fieldTemplateService;

    @Resource
    AsstWorkOrderService asstWorkOrderService;

    @Resource
    TcisService tcisService;

    @Resource
    WorkOrderCancelRecordMapper workorderCancelRecordMapper;

    @Resource
    HistoryAlarmMapper historyAlarmMapper;

    @Resource
    HistoryBrokenMapper historyBrokenMapper;

    @Resource
    WorkOrderHistoryMapper workOrderHistoryMapper;

    @Resource
    BusinessNoticeService businessNoticeService;

    @Resource
    DeviceStateMapper deviceStateMapper;

    @Autowired
    ConsumerService consumerService;

    @Autowired
    AppealLogService appealLogService;

    @Autowired
    HistoryAlarmService historyAlarmService;

    @Autowired
    HistoryBrokenService historyBrokenService;

    @Override
    public void cancelOrder(com.mingqijia.gassafety.webserver.dto.OrderCancelDTO dto) {
        try {
            QueryWrapper<FieldTemplate> templateQueryWrapper = new QueryWrapper<>();
            templateQueryWrapper.lambda().eq(FieldTemplate::getSpId, dto.getSpId())
                    .eq(FieldTemplate::getTemplateType, 1)
                    .eq(FieldTemplate::getIsDeleted, 0);
            FieldTemplate fieldTemplate = fieldTemplateService.getOne(templateQueryWrapper);
            String errMsg = "";
            try {
                //报警
                if (dto.getAppealType() == 0) {
                    if (fieldTemplate.getAlarmHandleType() == 2) {//时刻助手-报警器独立流程
                        OrderCancelDTO orderCancelDTO = new OrderCancelDTO();
                        orderCancelDTO.setOrderNo(dto.getOrderNo());
                        orderCancelDTO.setFromSystem(4);
                        orderCancelDTO.setCancelReason(dto.getRemark());
                        String targetSpId = consumerService.getConsumerRelateSpId(dto.getConsumerId(),dto.getSpId());
                        orderCancelDTO.setSpId(targetSpId);
                        asstWorkOrderService.cancelOrderV2(orderCancelDTO);
                    }else if (fieldTemplate.getAlarmHandleType() == 1){//新时刻助手
                        CancelBusiOrderDTO cancelBusiOrderDTO = new CancelBusiOrderDTO();
                        cancelBusiOrderDTO.setPkid(dto.getOrderNo());
                        cancelBusiOrderDTO.setOptcode("ALARM");
                        cancelBusiOrderDTO.setRemark(dto.getRemark());
                        tcisService.tcisRequestCancelBusiOrder(cancelBusiOrderDTO, String.valueOf(dto.getConsumerId()), dto.getSpId());
                    }
                } else { //故障
                    if (fieldTemplate.getBrokenHandleType() == 2) {//时刻助手-报警器独立流程
                        OrderCancelDTO orderCancelDTO = new OrderCancelDTO();
                        orderCancelDTO.setOrderNo(dto.getOrderNo());
                        orderCancelDTO.setFromSystem(4);
                        orderCancelDTO.setCancelReason(dto.getRemark());
                        String targetSpId = consumerService.getConsumerRelateSpId(dto.getConsumerId(),dto.getSpId());
                        orderCancelDTO.setSpId(targetSpId);
                        asstWorkOrderService.cancelOrderV2(orderCancelDTO);
                    } else {//新时刻助手
                        CancelBusiOrderDTO cancelBusiOrderDTO = new CancelBusiOrderDTO();
                        cancelBusiOrderDTO.setPkid(dto.getOrderNo());
                        cancelBusiOrderDTO.setOptcode("ALARM");
                        cancelBusiOrderDTO.setRemark(dto.getRemark());
                        tcisService.tcisRequestCancelBusiOrder(cancelBusiOrderDTO, String.valueOf(dto.getConsumerId()), dto.getSpId());
                    }
                }
            } catch (Exception e) {
                log.error("工单取消失败1",e);
                errMsg = e.getMessage();
                if( StringUtils.isEmpty(errMsg) ){
                    errMsg = "工单取消失败";
                }
                errMsg = errMsg.substring(0,Math.min(errMsg.length(),250));
            }
            WorkOrderCancelRecord workorderCancelRecord = getWorkorderCancelRecord(dto, errMsg, fieldTemplate);
            workorderCancelRecordMapper.insert(workorderCancelRecord);
        }catch (Exception e){
            log.error("取消工单失败",e);
        }
    }

    @Override
    public void cancelOrder(HistoryAlarm historyAlarm) {
        if (!checkIsAutoCancelWorkOrder(BusinessNoticeParam.ALARM_WORKORDER_AUTO_CANCEL.getCode(),
                historyAlarm.getSpId())) {
            log.info("cancelOrder:{}", "报警-未开启自动取消功能功能");
            return;
        }
        LambdaQueryWrapper<HistoryAlarm> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(HistoryAlarm::getIMEI,historyAlarm.getIMEI());
        queryWrapper.eq(HistoryAlarm::getSpId,historyAlarm.getSpId());
        queryWrapper.eq(HistoryAlarm::getConsumerId,historyAlarm.getConsumerId());
        queryWrapper.eq(HistoryAlarm::getIsDeleted, 0);
        queryWrapper.orderByDesc(HistoryAlarm::getId);
        queryWrapper.last("LIMIT 1");
        List<HistoryAlarm> historyAlarmList = historyAlarmMapper.selectList(queryWrapper);
        log.info("historyAlarmList:{}", JSONObject.toJSONString(historyAlarmList));
        if (historyAlarmList == null || historyAlarmList.isEmpty()) {
            return;
        }
        HistoryAlarm record = historyAlarmList.get(0);
        if (0 == record.getAppealStatus()) {
            alarmBrokenRecordAutoHandle(record.getId(), "设备上报报警恢复,无需处理", record.getSpId(), 0);
            return;
        }
        if( 0 == record.getWorkorderId() ){//非转工单处理
            log.info("cancelOrder:{}", "告警-非转工单处理");
            return;
        }
        if (1 != record.getAppealStatus()) {//非工单处理中
            log.info("cancelOrder:{}", "告警-非工单处理中");
            return;
        }
        List<Integer> alarmStatus = new ArrayList<>();
        alarmStatus.add(2);
        alarmStatus.add(3);
        alarmStatus.add(6);
        int cnt = deviceStateMapper.getWorkOrderImeisByStates(record.getSpId(),record.getWorkorderId(),alarmStatus);
        if (cnt>0){
            log.info("cancelOrder:报警设备未全部恢复报警:{}", cnt);
            return;
        }
        LambdaQueryWrapper<WorkOrderHistory> historyQueryWrapper = new LambdaQueryWrapper<>();
        historyQueryWrapper.eq(WorkOrderHistory::getId,record.getWorkorderId());
        historyQueryWrapper.eq(WorkOrderHistory::getIsDeleted,0);
        historyQueryWrapper.orderByDesc(WorkOrderHistory::getId);
        List<WorkOrderHistory> workOrderHistoryList = workOrderHistoryMapper.selectList(historyQueryWrapper);
        if (workOrderHistoryList == null || workOrderHistoryList.isEmpty()) {
            log.info("cancelOrder:{}", "告警-未找到工单记录");
            return;
        }
        WorkOrderHistory workOrderHistory = workOrderHistoryList.get(0);
        if( 1==workOrderHistory.getHandleStatus() ){//工单已完成
            log.info("cancelOrder:{}", "告警-工单已完成");
            return;
        }
        com.mingqijia.gassafety.webserver.dto.OrderCancelDTO orderCancelDTO = new com.mingqijia.gassafety.webserver.dto.OrderCancelDTO();
        orderCancelDTO.setAppealType(0);
        orderCancelDTO.setAlarmBrokenId(record.getId());
        orderCancelDTO.setSpId(historyAlarm.getSpId());
        String orderNo = workOrderHistory.getOrderNo();
        if ('S' == orderNo.charAt(orderNo.length() - 1)){
            orderNo = orderNo.substring(0, orderNo.length() - 1);
        }
        orderCancelDTO.setOrderNo(orderNo);
        orderCancelDTO.setConsumerId(historyAlarm.getConsumerId());
        orderCancelDTO.setRemark("报警设备告警恢复工单取消");
        cancelOrder(orderCancelDTO);
    }

    @Override
    public void cancelOrder(HistoryBroken historyBroken) {
        if (!checkIsAutoCancelWorkOrder(BusinessNoticeParam.BROKEN_WORKORDER_AUTO_CANCEL.getCode(),
                historyBroken.getSpId())) {
            log.info("cancelOrder:{}", "故障-未开启自动取消功能功能");
            return;
        }
        LambdaQueryWrapper<HistoryBroken> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(HistoryBroken::getIMEI,historyBroken.getIMEI());
        queryWrapper.eq(HistoryBroken::getSpId,historyBroken.getSpId());
        queryWrapper.eq(HistoryBroken::getConsumerId,historyBroken.getConsumerId());
        queryWrapper.eq(HistoryBroken::getIsDeleted, 0);
        queryWrapper.orderByDesc(HistoryBroken::getId);
        queryWrapper.last("LIMIT 1");
        List<HistoryBroken> historyBrokenList = historyBrokenMapper.selectList(queryWrapper);
        log.info("historyBrokenList:{}", JSONObject.toJSONString(historyBrokenList));
        if (historyBrokenList == null || historyBrokenList.isEmpty()) {
            return;
        }
        HistoryBroken record = historyBrokenList.get(0);
        if (0 == record.getAppealStatus()) {
            alarmBrokenRecordAutoHandle(record.getId(),"设备上报故障恢复,无需处理", record.getSpId(), 1);
            return;
        }
        if( 0 == record.getWorkorderId() ){//非转工单处理
            log.info("cancelOrder:{}", "故障-非转工单处理");
            return;
        }
        if (1 != record.getAppealStatus()) {//非工单处理中
            log.info("cancelOrder:{}", "故障-非工单处理中");
            return;
        }
        List<Integer> alarmStatus = new ArrayList<>();
        alarmStatus.add(4);
        int cnt = deviceStateMapper.getWorkOrderImeisByStatesBoken(record.getSpId(),record.getWorkorderId(),alarmStatus);
        if (cnt>0){
            log.info("cancelOrder:报警设备未全部恢复故障:{}", cnt);
            return;
        }
        LambdaQueryWrapper<WorkOrderHistory> historyQueryWrapper = new LambdaQueryWrapper<>();
        historyQueryWrapper.eq(WorkOrderHistory::getId,record.getWorkorderId());
        historyQueryWrapper.eq(WorkOrderHistory::getIsDeleted,0);
        historyQueryWrapper.orderByDesc(WorkOrderHistory::getId);
        List<WorkOrderHistory> workOrderHistoryList = workOrderHistoryMapper.selectList(historyQueryWrapper);
        if (workOrderHistoryList == null || workOrderHistoryList.isEmpty()) {
            log.info("cancelOrder:{}", "故障-未找到工单记录");
            return;
        }
        WorkOrderHistory workOrderHistory = workOrderHistoryList.get(0);
        if( 1==workOrderHistory.getHandleStatus() ){//工单已完成
            log.info("cancelOrder:{}", "故障-工单已完成");
            return;
        }
        com.mingqijia.gassafety.webserver.dto.OrderCancelDTO orderCancelDTO = new com.mingqijia.gassafety.webserver.dto.OrderCancelDTO();
        orderCancelDTO.setAppealType(1);
        orderCancelDTO.setAlarmBrokenId(record.getId());
        orderCancelDTO.setSpId(historyBroken.getSpId());
        String orderNo = workOrderHistory.getOrderNo();
        if ('S' == orderNo.charAt(orderNo.length() - 1)){
            orderNo = orderNo.substring(0, orderNo.length() - 1);
        }
        orderCancelDTO.setOrderNo(orderNo);
        orderCancelDTO.setConsumerId(historyBroken.getConsumerId());
        orderCancelDTO.setRemark("报警设备故障恢复工单取消");
        cancelOrder(orderCancelDTO);
    }

    private void alarmBrokenRecordAutoHandle(Long alarmBrokenId, String appealResult, String spId, Integer type){
        AppealLog appealLog = new AppealLog();
        appealLog.setAlarmBrokenId(alarmBrokenId);
        appealLog.setAppealStatus(Constants.APPEAL_STATUS_8);
        appealLog.setAppealResult(appealResult);
        appealLog.setSpId(spId);
        appealLog.setUserName("报警监控系统");
        appealLog.setUserAccount("");
        appealLog.setAppealType(type);
        appealLogService.save(appealLog);
        // 更新报警/故障信息记录主表
        if (appealLog.getAppealType() == null || appealLog.getAppealType() == 0) {
            LambdaUpdateWrapper<HistoryAlarm> historyAlarmWrapper = new LambdaUpdateWrapper<>();
            historyAlarmWrapper.eq(HistoryAlarm::getId,appealLog.getAlarmBrokenId()).eq(HistoryAlarm::getIsDeleted,0);
            HistoryAlarm historyAlarm = new HistoryAlarm();
            historyAlarm.setValveBrokenInfo("");
            historyAlarm.setWorkorderId(appealLog.getWorkorderId() == null ? 0L : appealLog.getWorkorderId());
            historyAlarm.setAppealStatus(appealLog.getAppealStatus());
            historyAlarm.setAppealResult(appealLog.getAppealResult());
            historyAlarm.setUserName(appealLog.getUserName());
            historyAlarm.setUserAccount(appealLog.getUserAccount());
            historyAlarm.setAppealTime(appealLog.getCreatedAt());
            boolean historyAlarmResult = historyAlarmService.update(historyAlarm,historyAlarmWrapper);
            log.info("alarmBrokenAutoHandelWhenRecovery->工单处理完成，更新报警器设备报警记录,结果：{}，内容：{}",historyAlarmResult,historyAlarm.toString());
        } else  if (appealLog.getAppealType() == 1) {
            LambdaUpdateWrapper<HistoryBroken> historyBrokenWrapper = new LambdaUpdateWrapper<>();
            historyBrokenWrapper.eq(HistoryBroken::getId,appealLog.getAlarmBrokenId()).eq(HistoryBroken::getIsDeleted,0);
            HistoryBroken historyBroken = new HistoryBroken();
            historyBroken.setValveBrokenInfo("");
            historyBroken.setWorkorderId(appealLog.getWorkorderId() == null ? 0L : appealLog.getWorkorderId());
            historyBroken.setAppealStatus(appealLog.getAppealStatus());
            historyBroken.setAppealResult(appealLog.getAppealResult());
            historyBroken.setUserName(appealLog.getUserName());
            historyBroken.setUserAccount(appealLog.getUserAccount());
            historyBroken.setAppealTime(appealLog.getCreatedAt());
            boolean historyBrokenResult = historyBrokenService.update(historyBroken,historyBrokenWrapper);
            log.info("alarmBrokenAutoHandelWhenRecovery->工单处理完成，更新报警器设备故障记录,结果：{}，内容：{}",historyBrokenResult,historyBroken.toString());
        }
    }
    /**
     * 是否开启自动取消工单功能
     * @param paramCode
     * @param spId
     * @return
     */
    private boolean checkIsAutoCancelWorkOrder(String paramCode, String spId) {
        Map<String,Object> qMap = new HashMap<>();
        qMap.put("spId", spId);
        qMap.put("paramCode", paramCode);
        List<BusinessNotice> list = businessNoticeService.selectParamList(qMap);
        if (!CollectionUtils.isEmpty(list) && list.get(0) != null && "ON".equals(list.get(0).getParamValue())) {
            return true;
        }
        return false;
    }

    private WorkOrderCancelRecord getWorkorderCancelRecord(com.mingqijia.gassafety.webserver.dto.OrderCancelDTO orderCancelDTO, String errMsg, FieldTemplate fieldTemplate) {
        int result = 0;
        if (!StringUtils.isEmpty(errMsg)) {//取消失败,记录到日志
            result = 1;
        }
        WorkOrderCancelRecord workorderCancelRecord = new WorkOrderCancelRecord();
        workorderCancelRecord.setConsumerId(orderCancelDTO.getConsumerId());
        workorderCancelRecord.setOrderNo(orderCancelDTO.getOrderNo());
        if (orderCancelDTO.getAppealType() == 0) {
            workorderCancelRecord.setWorkSystemType(fieldTemplate.getAlarmHandleType());
        } else {
            workorderCancelRecord.setWorkSystemType(fieldTemplate.getBrokenHandleType());
        }
        workorderCancelRecord.setResult(result);
        workorderCancelRecord.setErrorMsg(errMsg);
        workorderCancelRecord.setSpId(orderCancelDTO.getSpId());
        workorderCancelRecord.setAppealType(orderCancelDTO.getAppealType());
        workorderCancelRecord.setAlarmBrokenId(orderCancelDTO.getAlarmBrokenId());
        workorderCancelRecord.setRemark(orderCancelDTO.getRemark());
        return workorderCancelRecord;
    }
}
